﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;

namespace iMario
{
    public class MapManager : EntityManager
    {
        //Mục đích
        //  - Tập trung mọi thao tác xử lí và cập nhật bản đồ, vẽ bản đồ vào trong 1 lớp để tiện quản lí và dễ sử dụng
        //  - Cả chương trình game chỉ có 1 đối tượng thuộc lớp MapManager để quản lí và mọi giao tiếp với Map đều thông qua biến này

        
        //Danh sách các thuộc tính và ý nghĩa
        private Map _currentMap;                        //Map đang được sử dụng
        public Map currentMap
        {
            get { return _currentMap; }
        }

        private ContentManager _content;                //Đại diện cho Content của game
        public ContentManager content
        {
            get { return _content; }
        }

        private List<Monster> _monsters;                //Danh sách quái vật trong currentMap
        public List<Monster> monsters
        {
            get { return _monsters; }
            set { _monsters = value; }
        }

        private List<KindOfSprite> _kindOfMonsters;     //Danh sách các loại quái vật
        public List<KindOfSprite> kindOfMonsters
        {
            get { return _kindOfMonsters; }
            set { _kindOfMonsters = value; }
        }


        //Danh sách các hàm và ý nghĩa
        //Hàm dựng mặc định - Không có tham số truyền vào
        //  1. Tham số truyền vào: Không có
        //  2. Giá trị trả về: Không có
        public MapManager()
        {
            prototypes = new List<GameObject>();

            _content = null;

            _monsters = new List<Monster>();

            _kindOfMonsters = new List<KindOfSprite>();
        }

        //Hàm Khởi tạo và thiết lập các giá trị ban đầu của đối tượng thuộc lớp
        //  1. Tham số truyền vào
        //      - 
        //  2. Giá trị trả về: Không có
        public void Initial()
        {
            //Hướng xử lí
            //Kiểm tra: Nếu _content != null => Thực hiện tiếp các lệnh bên dưới
            //  1. Khởi tạo danh sách các prototype
            //  2. Khởi tạo danh sách các loại quái vật


            //Tiến hành
            //Kiểm tra: Nếu _content != null => Thực hiện tiếp các lệnh bên dưới
            if (_content == null)
                return;

            //  1. Khởi tạo danh sách các prototypes map
            //GameObject _map = new Map(@"Maps/Map_Demo.txt");
            GameObject _map = new Map(@"Maps/map_test3.txt");
            ((Map)_map).SetBackGround(_content.Load<Texture2D>(@"BackGround/BearVillage1"));
            ((Map)_map).SetTileBackGround(_content.Load<Texture2D>(@"TileBackGround/tile_map_grass"));
            prototypes.Add(_map);

            //  2. Khởi tạo danh sách các loại quái vật
            KindOfSprite _kind = new KindOfSprite(@"Mushroom", 3, new Point(16, 16));
            _kindOfMonsters.Add(_kind);
        }

        //Hàm tạo bản đồ mới từ những bản đồ có trong prototypes
        //  1. Tham số truyền vào
        //      - 
        //  2. Giá trị trả về: Không có
        public override GameObject CreateObject(int _iPrototype)
        {
            //Hướng xử lí
            //Kiểm tra: Nếu _iMap nằm trong khoảng [0, prototypes.Count) => Tiếp tục thực thi các câu lệnh bên dưới


            //Tiến hành
            //Kiểm tra: Nếu _iMap nằm trong khoảng [0, prototypes.Count) => Tiếp tục thực thi các câu lệnh bên dưới
            if (_iPrototype < 0 || _iPrototype >= prototypes.Count)
                return null;

            GameObject _map = (GameObject)prototypes[_iPrototype].Clone();

            return _map;
        }

        //Hàm xử lí các thao tác vẽ của map hiện tại
        //  1. Tham số truyền vào:
        //      - SpriteBatch _spriteBatch
        //      - GameTime _gameTime
        //  2. Giá trị trả về: Không có
        public void Draw(SpriteBatch _spriteBatch, GameTime _gameTime)
        {
            //Kiểm tra: Nếu _currentMap != null => Thực hiện tiếp các câu lệnh bên dưới
            if (_currentMap == null)
                return;

            _currentMap.Draw(_spriteBatch, _gameTime);
        }

        //Hàm xử lí các thao tác cập nhật cho bản đồ (di chuyển bản đồ)
        //  1. Tham số truyền vào:
        //      - KeyboardState _keyboard: Đại diện cho trạng thái hiện tại của keyboard
        //      - MouseState _mouse: Đại diện cho trạng thái hiện tại của mouse
        //      - GameTime _gameTime
        //  2. Giá trị trả về: Không có
        public void Update(KeyboardState _keyboard, MouseState _mouse, GameTime _gameTime)
        {
            //Kiểm tra: Nếu _currentMap != null => Thực hiện tiếp các câu lệnh bên dưới
            if (_currentMap == null)
                return;

            _currentMap.Update(_keyboard, _mouse, _gameTime);
        }

        //Hàm thiết lập giá trị _content cho đối tượng MapManager
        //  1. Tham số truyền vào
        //      - ContentManager _inputContent
        //  2. Giá trị trả về: Không có
        public void SetContent(ContentManager _inputContent)
        {
            _content = _inputContent;
        }

        //Hàm chọn bản đồ hiện tại cho currentMap
        //  1. Tham số truyền vào
        //      - int _iMap;
        //  2. Giá trị trả về: Không có
        public void SetCurrentMap(int _iMap)
        {
            //Hướng xử lí
            //Kiểm tra: Nếu _iMap nằm trong khoảng [0; prototypes.Count) => Thực hiện tiếp các lệnh bên dưới


            //Tiến hành
            //Kiểm tra: Nếu _iMap nằm trong khoảng [0; prototypes.Count) => Thực hiện tiếp các lệnh bên dưới
            if (_iMap < 0 || _iMap >= prototypes.Count)
                return;

            _currentMap = (Map)this.CreateObject(_iMap);
        }
    }
}
